#pragma once
/**
 * @file mqttmgr.h
 * @brief mqtt客户端封装提供mqtt初始化，订阅发布等接口
 * @author ypj
 * @date 2024年3月21日
 * @license MIT Apache2.0
 * Copyright (C), 2010-2022 Jouav Co., Ltd.
 */

#include <mosquitto.h>
#include <mosquittopp.h>
#include <functional>
#include <string>
#include <map>

namespace jouav
{
    /**
     *  @brief 类名 MqttMgr
     *  @function MQTT客户端接口封装，单例，对外提供初始化，订阅和发布接口
     */
    class MqttMgr : public mosqpp::mosquittopp
    {
    public:
        virtual ~MqttMgr();
        /**
         * @brief 单例接口获取MQMgr的实例化对象
         * @return MQMgr实例化对象
         */
        static MqttMgr& GetInstance();

        //using mqttsub_cb = std::function<int(const char* topic, const void* data, int sz)>;
        typedef int (*mqttsub_cb)(const char* topic, const void* data, int sz);

        /**
         * @brief MQTT初始化
         * @return 0:成功 -1:失败
         */
        int Init();

        /*!
         * @brief 添加订阅
         * @param topic_ 订阅主题
         * @param func_ 回调函数
         * @return int: 0:没有错误
         * @note 回调函数返回
         */
        virtual int Subscribe(const std::string& topic_/*, mqttsub_cb func*/);

        /*!
         * @brief 设置订阅回调函数
         * @param topic_ 订阅主题
         * @param func_ 回调函数
         * @return int: 0:没有错误
         * @note 回调函数返回
         */
        virtual int SetSubCb(mqttsub_cb func_);

        /*!
         * @brief 取消订阅
         * @param topic_ 取消订阅的Topic
         * @return int: 0:没有错误 -1:内部错误
         */
        virtual int UnSubscribe(const std::string& topic_);

        /*!
        * @brief 发布消息
        * @param topic_ 发布主题
        * @param data_ 数据
        * @param len_ 长度 ，-1失败
        * @return int: 0:没有错误 -1:内部错误
        */
        virtual int Publish(const std::string& topic_, const void* data_, size_t len_);

    protected:
        virtual void on_connect(int /*rc*/);
        virtual void on_connect_with_flags(int /*rc*/, int /*flags*/);
        virtual void on_disconnect(int /*rc*/);
        virtual void on_publish(int /*mid*/);
        virtual void on_message(const struct mosquitto_message* /*message*/);
        virtual void on_subscribe(int /*mid*/, int /*qos_count*/, const int* /*granted_qos*/);
        virtual void on_unsubscribe(int /*mid*/);
        virtual void on_log(int /*level*/, const char* /*str*/);
        virtual void on_error();

    private:
        MqttMgr();

    private:
        bool is_connect_ = false;
        //std::map<std::string, mqttsub_cb> map_callback_;
        mqttsub_cb cb_;
    };

}// namespace jouav
